// Sales Order Shopify logistics management
frappe.listview_settings['Sales Order'].refresh = function(listview) {
	// Add menu item: fetch Shopify fulfillment info
	listview.page.add_menu_item(__("Get Shopify Fulfillments"), function() {
		get_shopify_fulfillments(listview);
	});
	
	// Add menu item: modify Shopify fulfillment
	listview.page.add_menu_item(__("Modify Shopify Fulfillment"), function() {
		modify_shopify_fulfillments(listview);
	});
	
	// Add menu item: manual fulfillment
	listview.page.add_menu_item(__("Manual Fulfillment"), function() {
		manual_fulfillment(listview);
	});
};

const INTERNAL_TRACKING_BASE_URL = "https://oms.flowa.global/tms_tracking";
const USPS_TRACK_URL = "http://tools.usps.com/go/TrackConfirmAction?tLabels=";
const EVRI_TRACK_URL = "https://www.evri.com/track/parcel/";
const DHL_TRACK_URL = "https://www.dhl.com/global-en/home/tracking/tracking-express.html?submit=1&tracking-id=";
const GENERIC_17TRACK_URL = "https://www.17track.net/en?nums=";

const COUNTRY_CODE_ALIASES = {
    "UNITED STATES": "US",
    "UNITED STATES OF AMERICA": "US",
    "USA": "US",
    "AMERICA": "US",
    "UNITED KINGDOM": "GB",
    "GREAT BRITAIN": "GB",
    "ENGLAND": "GB",
    "UK": "GB",
    "GERMANY": "DE",
    "DEUTSCHLAND": "DE",
    "FRANCE": "FR",
    "SPAIN": "ES",
    "ESPANA": "ES",
    "NETHERLANDS": "NL",
    "THE NETHERLANDS": "NL",
    "HOLLAND": "NL"
};

const COUNTRY_CODE_ALIAS_LOOKUP = Object.keys(COUNTRY_CODE_ALIASES).reduce((acc, key) => {
    acc[key.toLowerCase()] = COUNTRY_CODE_ALIASES[key];
    return acc;
}, {});

const BASE_SPECIAL_TRACKING_RULES = {
    US: { carrier: "USPS", urlTemplate: USPS_TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] },
    GB: { carrier: "Evri", urlTemplate: EVRI_TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] },
    DE: { carrier: "DHL", urlTemplate: DHL_TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] },
    FR: { carrier: "Colisprive", urlTemplate: GENERIC_17TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] },
    ES: { carrier: "CTT", urlTemplate: GENERIC_17TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] }
};

const SPECIAL_TRACKING_RULES = {
    YTYCPREC: { ...BASE_SPECIAL_TRACKING_RULES },
    YTYCPREG: { ...BASE_SPECIAL_TRACKING_RULES, NL: { carrier: "DHL", urlTemplate: DHL_TRACK_URL, numberSource: ["custom_delivery_no", "custom_delivery_order_no"] } }
};

// Get Shopify fulfillment info
function get_shopify_fulfillments(listview) {
	const selected_orders = listview.get_checked_items();
	
	if (selected_orders.length === 0) {
		frappe.msgprint(__("Please select at least one Sales Order"));
		return;
	}
	
	if (selected_orders.length > 1) {
		frappe.msgprint(__("Please select exactly one Sales Order"));
		return;
	}
	
	const order = selected_orders[0];
	
	// Check shopify_order_id exists
	if (!order.custom_shopify_order_id || order.custom_shopify_order_id === '0' || order.custom_shopify_order_id.length < 10) {
		frappe.msgprint(__("This is not a Shopify order; cannot fetch fulfillment info"));
		return;
	}
	
	// Use order name directly
	frappe.call({
		method: "upsystem.upsystem.api_shop.get_shopify_order_fulfillments",
		args: {
			sales_order_name: order.name
		},
		callback: function(response) {
			if (response.message && response.message.success) {
				show_fulfillment_info(response.message.data);
			} else {
				frappe.msgprint(__("Failed to fetch fulfillment info: {0}", [response.message.error || "Unknown error"]));
			}
		}
	});
}

// Modify Shopify fulfillment
function modify_shopify_fulfillments(listview) {
	const selected_orders = listview.get_checked_items();
	
	if (selected_orders.length === 0) {
		frappe.msgprint(__("Please select at least one Sales Order"));
		return;
	}
	
	if (selected_orders.length > 1) {
		frappe.msgprint(__("Please select exactly one Sales Order"));
		return;
	}
	
	const order = selected_orders[0];
	hydrateOrderForTracking(order).then((hydrated) => {

		if (!hydrated.custom_shopify_order_id || hydrated.custom_shopify_order_id === '0' || hydrated.custom_shopify_order_id.length < 10) {
			frappe.msgprint(__("This is not a Shopify order; cannot modify fulfillment info"));
			return;
		}

		frappe.call({
			method: "upsystem.upsystem.api_shop.get_shopify_order_fulfillments",
			args: {
				sales_order_name: order.name
			},
			callback: function(response) {
				if (response.message && response.message.success) {
					show_modify_fulfillment_dialog(response.message.data, order.name, hydrated);
				} else {
					frappe.msgprint(__("Failed to fetch fulfillment info: {0}", [response.message.error || "Unknown error"]));
				}
			}
		});
	});
}

// Manual fulfillment
function manual_fulfillment(listview) {
	const selected_orders = listview.get_checked_items();
	
	if (selected_orders.length === 0) {
		frappe.msgprint(__("Please select at least one Sales Order"));
		return;
	}
	
	if (selected_orders.length > 1) {
		frappe.msgprint(__("Please select exactly one Sales Order"));
		return;
	}
	
	const order = selected_orders[0];
	
	// Check shopify_order_id exists
	if (!order.custom_shopify_order_id || order.custom_shopify_order_id === '0' || order.custom_shopify_order_id.length < 10) {
		frappe.msgprint(__("This is not a Shopify order; cannot perform manual fulfillment"));
		return;
	}
	
	// Check order status
	if (order.status !== 'To Deliver' && order.status !== 'Submitted') {
		frappe.msgprint(__("Only \"To Deliver\" or \"Submitted\" orders can be fulfilled manually"));
		return;
	}
	
	frappe.confirm(
		__("Are you sure to manually fulfill order '{0}'?\n\nThis will:\n1. Sync to WDT\n2. Update Shopify fulfillment info", [order.name]),
		function() {
			process_manual_fulfillment(order);
		}
	);
}

// Process manual fulfillment
function process_manual_fulfillment(order) {
	frappe.show_alert({
		message: __("Syncing to WDT..."),
		indicator: 'blue'
	});
	
	// 1. Sync to WDT first
	frappe.call({
		method: "upsystem.upsystem.api.sync_sales_order_to_wdt",
		args: {
			sales_order_name: order.name
		},
		callback: function(response) {
			if (response.message && response.message.success) {
				frappe.show_alert({
					message: __("WDT sync succeeded, updating Shopify fulfillment info..."),
					indicator: 'blue'
				});
				if (response.message.reserve_info && typeof maybe_show_low_balance_dialog === "function") {
					maybe_show_low_balance_dialog(response.message.reserve_info);
				}
				
				// 2. Update Shopify fulfillment
				update_shopify_fulfillment_with_wdt_data(order);
			} else {
				frappe.msgprint(__("WDT sync failed: {0}", [response.message.message || "Unknown error"]));
			}
		}
	});
}

// Update Shopify fulfillment using WDT data
function update_shopify_fulfillment_with_wdt_data(order) {
	hydrateOrderForTracking(order).then((hydrated) => {
		const shop_name = get_shop_name_from_order(hydrated);
		if (!shop_name) {
			frappe.msgprint(__("Unable to get shop name"));
			return;
		}

		const resolved = resolveTrackingDetails(hydrated);
		const tracking_number = resolved.tracking_number;
		const carrier = resolved.carrier || 'Flowa';
		const tracking_url = resolved.tracking_url || buildInternalTrackingUrl(tracking_number);

		if (!tracking_number) {
			frappe.msgprint(__("Tracking number not found; please sync to WDT first"));
			return;
		}

		get_fulfillment_orders_for_update(order.name, function(fulfillment_orders) {
			if (fulfillment_orders.length === 0) {
				frappe.msgprint(__("Unable to get fulfillment orders; please check order status"));
				return;
			}

			frappe.call({
				method: "upsystem.upsystem.api_shop.update_shopify_fulfillment",
				args: {
					sales_order_name: order.name,
					tracking_number: tracking_number,
					fulfillment_orders: fulfillment_orders,
					tracking_url: tracking_url,
					carrier: carrier
				},
				callback: function(response) {
					if (response.message && response.message.success) {
						frappe.show_alert({
							message: __("Manual fulfillment completed! Tracking number: {0}", [tracking_number]),
							indicator: 'green'
						});
						listview.refresh();
					} else {
						frappe.msgprint(__("Shopify fulfillment update failed: {0}", [response.message.error || "Unknown error"]));
					}
				}
			});
		});
	});
}

// Show fulfillment info dialog
function show_fulfillment_info(data) {
    let html = '<div style="max-height: 500px; overflow-y: auto;">';
    
    // Order info
    html += '<h4>Order Info</h4>';
    html += '<p><strong>Order No:</strong> ' + (data.order.name || 'N/A') + '</p>';
    html += '<p><strong>Financial Status:</strong> ' + (data.order.financial_status || 'N/A') + '</p>';
    html += '<p><strong>Fulfillment Status:</strong> ' + (data.order.fulfillment_status || 'N/A') + '</p>';
    
    // Fulfillments
    if (data.fulfillments && data.fulfillments.length > 0) {
        html += '<h4>Fulfillments</h4>';
        data.fulfillments.forEach((fulfillment, index) => {
            html += '<div style="border: 1px solid #ddd; margin: 10px 0; padding: 10px;">';
            html += '<p><strong>Fulfillment #' + (index + 1) + '</strong></p>';
            html += '<p><strong>Status:</strong> ' + (fulfillment.status || 'N/A') + '</p>';
            html += '<p><strong>Created At:</strong> ' + (fulfillment.created_at || 'N/A') + '</p>';
            
            if (fulfillment.tracking_info) {
                html += '<p><strong>Tracking No:</strong> ' + (fulfillment.tracking_info.number || 'N/A') + '</p>';
                html += '<p><strong>Carrier:</strong> ' + (fulfillment.tracking_info.company || 'N/A') + '</p>';
                if (fulfillment.tracking_info.url) {
                    html += '<p><strong>Tracking URL:</strong> <a href="' + fulfillment.tracking_info.url + '" target="_blank">' + fulfillment.tracking_info.url + '</a></p>';
                }
            }
            
            if (fulfillment.line_items && fulfillment.line_items.length > 0) {
                html += '<p><strong>Items:</strong></p><ul>';
                fulfillment.line_items.forEach(item => {
                    html += '<li>' + (item.line_item.title || 'N/A') + ' x ' + (item.quantity || 0) + '</li>';
                });
                html += '</ul>';
            }
            
            html += '</div>';
        });
    } else {
        html += '<p>No fulfillment records</p>';
    }
    
    // Fulfillment orders
    if (data.fulfillment_orders && data.fulfillment_orders.length > 0) {
        html += '<h4>Fulfillment Orders</h4>';
        data.fulfillment_orders.forEach((fulfillment_order, index) => {
            html += '<div style="border: 1px solid #ddd; margin: 10px 0; padding: 10px;">';
            html += '<p><strong>Fulfillment Order #' + (index + 1) + '</strong></p>';
            html += '<p><strong>Status:</strong> ' + (fulfillment_order.status || 'N/A') + '</p>';
            
            if (fulfillment_order.assigned_location) {
                html += '<p><strong>Assigned Location:</strong> ' + (fulfillment_order.assigned_location.name || 'N/A') + '</p>';
            }
            
            if (fulfillment_order.line_items && fulfillment_order.line_items.length > 0) {
                html += '<p><strong>Items:</strong></p><ul>';
                fulfillment_order.line_items.forEach(item => {
                    html += '<li>' + (item.line_item.title || 'N/A') + ' - Remaining: ' + (item.remaining_quantity || 0) + ' / Total: ' + (item.total_quantity || 0) + '</li>';
                });
                html += '</ul>';
            }
            
            html += '</div>';
        });
    }
    
    html += '</div>';
    
    const dialog = new frappe.ui.Dialog({
        title: __('Shopify Fulfillment Info'),
        size: 'large',
        fields: [
            {
                fieldtype: 'HTML',
                fieldname: 'fulfillment_info',
                options: html
            }
        ],
        primary_action_label: __('Close'),
        primary_action: function() {
            dialog.hide();
        }
    });
    
    dialog.show();
}

// Show modify fulfillment dialog
function show_modify_fulfillment_dialog(data, sales_order_name, order_row) {
	let html = '<div style="max-height: 400px; overflow-y: auto;">';
	
	// Show current fulfillment
	if (data.fulfillments && data.fulfillments.length > 0) {
		html += '<h4>Current Fulfillment Info</h4>';
		data.fulfillments.forEach((fulfillment, index) => {
			html += '<div style="border: 1px solid #ddd; margin: 10px 0; padding: 10px;">';
			html += '<p><strong>Fulfillment #' + (index + 1) + '</strong></p>';
			html += '<p><strong>Status:</strong> ' + (fulfillment.status || 'N/A') + '</p>';
			
			if (fulfillment.tracking_info) {
				html += '<p><strong>Current Tracking No:</strong> ' + (fulfillment.tracking_info.number || 'N/A') + '</p>';
				html += '<p><strong>Current Carrier:</strong> ' + (fulfillment.tracking_info.company || 'N/A') + '</p>';
				if (fulfillment.tracking_info.url) {
					html += '<p><strong>Current Tracking URL:</strong> <a href="' + fulfillment.tracking_info.url + '" target="_blank">' + fulfillment.tracking_info.url + '</a></p>';
				}
			}
			html += '</div>';
		});
	} else {
		html += '<p>No fulfillment records</p>';
	}
	
	html += '</div>';
	
	const trackingDefaults = resolveTrackingDetails(order_row);
	
	const dialog = new frappe.ui.Dialog({
		title: __('Modify Shopify Fulfillment Info'),
		size: 'large',
		fields: [
			{
				fieldtype: 'HTML',
				fieldname: 'current_info',
				options: html
			},
			{
				fieldtype: 'Section Break',
				fieldname: 'new_info_section',
				label: __('New Fulfillment Info')
			},
			{
				fieldtype: 'Data',
				fieldname: 'tracking_number',
				label: __('Tracking Number'),
				reqd: 1,
				default: trackingDefaults.tracking_number || ''
			},
			{
				fieldtype: 'Data',
				fieldname: 'carrier',
				label: __('Carrier'),
				default: trackingDefaults.carrier || 'Flowa'
			},
			{
				fieldtype: 'Data',
				fieldname: 'tracking_url',
				label: __('Tracking URL'),
				default: trackingDefaults.tracking_url || buildInternalTrackingUrl('')
			}
		],
		primary_action_label: __('Update Fulfillment Info'),
		primary_action: function(values) {
			update_fulfillment_tracking(sales_order_name, values, order_row);
			dialog.hide();
		},
		secondary_action_label: __('Cancel'),
		secondary_action: function() {
			dialog.hide();
		}
	});
	
	dialog.show();
}

function hydrateOrderForTracking(orderRow) {
    return new Promise((resolve) => {
        if (!orderRow || !orderRow.name) {
            resolve(orderRow || {});
            return;
        }

        frappe.call({
            method: 'frappe.client.get',
            args: {
                doctype: 'Sales Order',
                name: orderRow.name
            },
            callback: function(response) {
                const doc = response.message || {};
                const merged = Object.assign({}, orderRow, doc);
                merged.custom_yt_product_code = doc.custom_yt_product_code || orderRow.custom_yt_product_code;
                merged.custom_country = doc.custom_country || orderRow.custom_country;
                merged.custom_destination_country = doc.custom_destination_country || orderRow.custom_destination_country;
                merged.custom_destination_country_name = doc.custom_destination_country_name || orderRow.custom_destination_country_name;
                merged.custom_shop_name = doc.custom_shop_name || orderRow.custom_shop_name;
                merged.custom_delivery_no = doc.custom_delivery_no || orderRow.custom_delivery_no;
                merged.custom_delivery_order_no = doc.custom_delivery_order_no || orderRow.custom_delivery_order_no;
                resolve(merged);
            },
            error: function() {
                resolve(orderRow || {});
            }
        });
    });
}

// Update fulfillment tracking info
function update_fulfillment_tracking(sales_order_name, values, order_row) {
	const resolved = resolveTrackingDetails(order_row, values);
	if (!resolved.tracking_number) {
		frappe.msgprint(__("Please enter a tracking number"));
		return;
	}
	
	frappe.call({
		method: "upsystem.upsystem.api_shop.update_shopify_fulfillment_tracking",
		args: {
			sales_order_name: sales_order_name,
			tracking_number: resolved.tracking_number,
			tracking_url: resolved.tracking_url,
			carrier: resolved.carrier
		},
		callback: function(response) {
			if (response.message && response.message.success) {
				frappe.show_alert({
					message: __("Fulfillment info updated successfully! Tracking number: {0}", [resolved.tracking_number]),
					indicator: 'green'
				});
				listview.refresh();
			} else {
				frappe.msgprint(__("Failed to update fulfillment info: {0}", [response.message.error || "Unknown error"]));
			}
		}
	});
}

// Get shop name from order
function get_shop_name_from_order(order) {
	// Try field: shop_name
	if (order.shop_name) {
		return order.shop_name;
	}
	
	// Try field: custom_shop_name
	if (order.custom_shop_name) {
		return order.custom_shop_name;
	}
	
	// If missing, warn
	frappe.msgprint(__("Unable to get shop name, please check order configuration"));
	return null;
}

// Build fulfillment_orders data from order
function build_fulfillment_orders_from_order(order) {
	// Build based on order data (placeholder)
	// We cannot directly get Shopify fulfillment orders from Sales Order
	// Call get_shopify_order_fulfillments to obtain the correct structure first
	
	// Simplified implementation; fetch correct fulfillment order data in production
	return [
		{
			fulfillmentOrderId: order.custom_shopify_order_id,
			fulfillmentOrderLineItems: [
				{
					id: "line_item_id", // fetched from Shopify API
					quantity: 1 // fetched from Shopify API
				}
			]
		}
	];
}

// Fetch correct fulfillment_orders data
function get_fulfillment_orders_for_update(sales_order_name, callback) {
	frappe.call({
		method: "upsystem.upsystem.api_shop.get_shopify_order_fulfillments",
		args: {
			sales_order_name: sales_order_name
		},
		callback: function(response) {
			if (response.message && response.message.success) {
				const fulfillment_orders = [];
				
				// Build update payload from fulfillment_orders
				if (response.message.data.fulfillment_orders) {
					response.message.data.fulfillment_orders.forEach(fulfillment_order => {
						const line_items = [];
						if (fulfillment_order.line_items) {
							fulfillment_order.line_items.forEach(item => {
								line_items.push({
									id: item.id,
									quantity: item.remaining_quantity || item.total_quantity || 1
								});
							});
						}
						
						fulfillment_orders.push({
							fulfillmentOrderId: fulfillment_order.id,
							fulfillmentOrderLineItems: line_items
						});
					});
				}
				
				callback(fulfillment_orders);
			} else {
				frappe.msgprint(__("Failed to get fulfillment order data: {0}", [response.message.error || "Unknown error"]));
				callback([]);
			}
		}
	});
}

function resolveTrackingDetails(orderRow, overrides = {}) {
    const order = orderRow || {};
    const productCode = normalizeUpper(order.custom_yt_product_code || order.yt_product_code || order.custom_product_code);
    const countryCode = resolveCountryCode(order);

    

    const overrideNumber = trimOrEmpty(overrides.tracking_number);
    const overrideCarrier = trimOrEmpty(overrides.carrier);
    const overrideUrl = trimOrEmpty(overrides.tracking_url);

    const productRules = SPECIAL_TRACKING_RULES[productCode] || {};
    const rule = productRules[countryCode];

    let trackingNumber = overrideNumber;
    let carrier = overrideCarrier;
    let trackingUrl = overrideUrl;

    if (rule) {
        if (!trackingNumber) {
            trackingNumber = pickTrackingNumber(order, rule.numberSource) || pickTrackingNumber(order, ["custom_delivery_no", "custom_delivery_order_no"]);
        }
        
        if (!carrier) {
            carrier = rule.carrier || '';
        }
        if (!trackingUrl) {
            const tpl = rule.urlTemplate;
            if (tpl) {
                trackingUrl = trackingNumber ? `${tpl}${encodeURIComponent(trackingNumber)}` : tpl;
            }
        }
    } else {
        if (trackingNumber) {
            trackingNumber = ensureFgPrefix(trackingNumber);
        } else {
            trackingNumber = ensureFgPrefix(pickTrackingNumber(order, ["custom_delivery_order_no", "custom_delivery_no"])) || '';
        }
        if (!carrier) {
            carrier = 'Flowa';
        }
        if (!trackingUrl) {
            trackingUrl = buildInternalTrackingUrl(trackingNumber);
        }
    }

    if (!trackingUrl) {
        trackingUrl = buildInternalTrackingUrl(trackingNumber);
    }
    if (!carrier && trackingNumber) {
        carrier = 'Flowa';
    }

    const result = {
        tracking_number: trackingNumber || '',
        carrier: carrier || '',
        tracking_url: trackingUrl || ''
    };
    
    return result;
}

function pickTrackingNumber(orderRow, preferences) {
    const fields = Array.isArray(preferences) ? preferences : [preferences];
    for (const field of fields) {
        if (!field) continue;
        const value = orderRow && orderRow[field];
        if (value) {
            const trimmed = trimOrEmpty(value);
            if (trimmed) {
                return trimmed;
            }
        }
    }
    return '';
}

function ensureFgPrefix(num) {
    const value = trimOrEmpty(num);
    if (!value) {
        return '';
    }
    if (value.length >= 2 && value.slice(0, 2).toUpperCase() === 'FG') {
        return value;
    }
    if (value.length <= 2) {
        return `FG${value}`;
    }
    return `FG${value.slice(2)}`;
}

function buildInternalTrackingUrl(number) {
    const num = trimOrEmpty(number);
    if (num) {
        // 注意：后端路由只在 /tms_tracking 生效，带斜杠 /tms_tracking/ 会被服务器重定向到 127.0.0.1
        // 因此这里拼接为 '?num=' 而不在前面加 '/'
        return `${INTERNAL_TRACKING_BASE_URL}?num=${encodeURIComponent(num)}`;
    }
    return INTERNAL_TRACKING_BASE_URL;
}

function trimOrEmpty(value) {
    return value ? String(value).trim() : '';
}

function normalizeUpper(value) {
    const trimmed = trimOrEmpty(value);
    return trimmed ? trimmed.toUpperCase() : '';
}

function normalizeLower(value) {
    const trimmed = trimOrEmpty(value);
    return trimmed ? trimmed.toLowerCase() : '';
}

function resolveCountryCode(order) {
    const raw = trimOrEmpty(order.custom_country);
    if (!raw) {
        frappe.throw(__("Destination country (custom_country) is required on the Sales Order."));
    }

    const upper = normalizeUpper(raw);
    if (upper.length === 2) {
        return upper;
    }

    const aliasMatch = COUNTRY_CODE_ALIAS_LOOKUP[normalizeLower(raw)];
    if (aliasMatch) {
        return aliasMatch;
    }

    frappe.throw(
        __("Destination country '{0}' is invalid. Please pick a valid Country record.", [raw])
    );
}
